package com.zxj.transfer.bank1.service;

import com.zxj.transfer.api.service.Bank1Service;
import com.zxj.transfer.api.service.Bank2Service;
import com.zxj.transfer.orm.service.TCancelLogService;
import com.zxj.transfer.orm.service.TConfirmLogService;
import com.zxj.transfer.orm.service.TTryLogService;
import com.zxj.transfer.orm.service.UserAccountService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.dromara.hmily.annotation.HmilyTCC;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;

@Slf4j
@DubboService(version = "1.0.0", tag = "red", weight = 100)
public class Bank1ServiceImpl implements Bank1Service {

    @Autowired
    private TTryLogService tryLogService;
    @Autowired
    private TConfirmLogService confirmLogService;
    @Autowired
    private TCancelLogService cancelLogService;
    @Autowired
    private UserAccountService userAccountService;

    @DubboReference(version = "1.0.0")
    Bank2Service bank2Service;

    /**
     * @HmilyTCC与@Hmily
     *
     * RPC上面的Hmily注解的作用只是用于连接前后两个微服务的，使它们处于同一个分布式事务之下。
     * 比如Feign调用的库存服务：
     * @param tid
     * @param userIdA
     * @param usAccount
     * @param userIdB
     * @param rmbAccount
     */
    @Override
    @HmilyTCC(confirmMethod = "confirm", cancelMethod = "cancel")
    public void changeUs(String tid, Integer userIdA, BigDecimal usAccount, Integer userIdB, BigDecimal rmbAccount) {
        log.info("Bank1ServiceImpl.changeUs执行");
        if (tryLogService.isExist(tid)) {
            return;
        }
        if (confirmLogService.isExist(tid) || cancelLogService.isExist(tid)) {
            return;
        }
        // 冻结美元，插入try日志
        userAccountService.subtractUsAccount(userIdA, tid, usAccount);
        // B账户操作
        bank2Service.changeRmb(tid, userIdA, usAccount, userIdB, rmbAccount);
    }

    public void confirm(String tid, Integer userIdA, BigDecimal usAccount, Integer userIdB, BigDecimal rmbAccount) {
        log.info("Bank1ServiceImpl.confirmUs执行");
        if (!confirmLogService.isExist(tid)) {
            if (tryLogService.isExist(tid) && !cancelLogService.isExist(tid)) {
                userAccountService.confirmSubtractUsAccount(userIdA, tid, rmbAccount);
            }
        }
    }

    public void cancel(String tid, Integer userIdA, BigDecimal usAccount, Integer userIdB, BigDecimal rmbAccount) {
        log.info("Bank1ServiceImpl.cancelUs执行");
        if (!cancelLogService.isExist(tid)) {
            if (tryLogService.isExist(tid)) {
                if (confirmLogService.isExist(tid)) {
                    userAccountService.cancelSubtractUsAccountConfirm(userIdA, tid, usAccount, rmbAccount);
                } else {
                    userAccountService.cancelSubtractUsAccountNoConfirm(userIdA, tid, usAccount);
                }
            }
        }
    }
}
